﻿using System;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OAuthApp.Tenant;
using OAuthApp.Services;
using Swashbuckle.AspNetCore.Annotations;
using OAuthApp.Filters;
using System.IO;
using Microsoft.CodeAnalysis.FlowAnalysis.DataFlow.ValueContentAnalysis;
using ServiceStack;
using System.Collections.Generic;
using Microsoft.Build.Framework;
using System.ComponentModel.DataAnnotations;
using System.Web;

namespace OAuthApp.Apis
{
    [SwaggerTag("租户文件")]
    [ServiceFilter(typeof(ApiRequestLoggingAttribute))]
    public class TenantBlobsController : BaseController
    {
        private readonly UploadService _uploader;

        public TenantBlobsController(
            TenantDbContext context,
            UploadService uploader,
            IHttpContextAccessor contextAccessor)
        {
            _tenantContext = context;
            _uploader = uploader;
            _tenant = contextAccessor.HttpContext.GetTenantContext();
        }

        string blobRoot
        {
            get
            {
                return Path.Combine(
                    AppConst.BlobRoot,
                    _tenant.Id.ToString(),
                    Request.RouteValues["channelCode"].ToString(),
                    Request.RouteValues["appId"].ToString());
            }
        }

        //[HttpGet]
        //[SwaggerOperation(OperationId = "TenantBlobs")]
        //[EncryptResultFilter]
        //public IActionResult List(string channelCode,string channelAppId,string tag)
        //{
        //    var q = _tenantContext.TenantBlobs.Where(x => x.TenantID == _tenant.Id);

        //    if(!string.IsNullOrWhiteSpace(channelCode))
        //    {
        //        q = q.Where(x => x.ChannelCode.Equals(channelCode));
        //    }

        //    if (!string.IsNullOrWhiteSpace(channelAppId))
        //    {
        //        q = q.Where(x => x.ChannelAppID.Equals(channelAppId));
        //    }

        //    if (!string.IsNullOrWhiteSpace(tag))
        //    {
        //        q = q.Where(x => x.Tag.Contains(tag));
        //    }

        //    var result = q.ToList();

        //    return OK(result);
        //}

        //[HttpGet("{id}")]
        //[SwaggerOperation(OperationId = "TenantBlob")]
        //[EncryptResultFilter]
        //public IActionResult Get(long id)
        //{
        //    var result = _tenantContext.TenantBlobs.Find(id);

        //    if (result == null)
        //    {
        //        return NotFound();
        //    }

        //    return OK(result);
        //}

        //[HttpPut("{id}")]
        //[SwaggerOperation(OperationId = "TenantBlobPut")]
        //public IActionResult Put(long id, TenantBlob tenantBlob)
        //{
        //    if (id != tenantBlob.ID)
        //    {
        //        return BadRequest();
        //    }

        //    _tenantContext.Entry(tenantBlob).State = EntityState.Modified;

        //    try
        //    {
        //        _tenantContext.SaveChanges();
        //    }
        //    catch (Exception ex)
        //    {
        //        return Error(ex.Message);
        //    }

        //    return OK(true);
        //}

        //[HttpPost]
        //[SwaggerOperation(OperationId = "TenantBlobPost")]
        //public IActionResult Post(TenantBlob tenantBlob)
        //{
        //    tenantBlob.TenantID = _tenant.Id;

        //    _tenantContext.TenantBlobs.Add(tenantBlob);

        //    _tenantContext.SaveChanges();

        //    return OK(new { id = tenantBlob.ID });
        //}

        [HttpGet("{channelCode}/{appId}")]
        [SwaggerOperation(OperationId = "TenantBlobs")]
        [EncryptResultFilter]
        public IActionResult List([FromRoute]string channelCode, [FromRoute]string appId, string path)
        {
            var _path = string.Empty;

            if (!string.IsNullOrWhiteSpace(path) && path.Length > 1)
            {
                _path = Path.Combine(blobRoot, path.Substring(1));
            }
            else
            {
                _path = blobRoot;
            }

            if (Directory.Exists(_path))
            {
                var dir = new DirectoryInfo(_path);

                var directories = dir.GetDirectories().Select(x => new
                {
                    name = x.Name,
                    createDate = x.CreationTime,
                    lastUpdate = x.LastWriteTime
                });

                var files = dir.GetFiles().Select(x => new
                {
                    name = x.Name,
                    createDate = x.CreationTime,
                    lastUpdate = x.LastWriteTime,
                    fileSize = x.Length
                });

                //var directories = Directory.GetDirectories(_path).Select(d => Path.GetFileName(d));

                //var files = Directory.GetFiles(_path).Select(d => Path.GetFileName(d));

                return OK(new
                {
                    directories,
                    files
                });
            }

            return Ok();
        }

        
        [HttpDelete("{channelCode}/{appId}")]
        [SwaggerOperation(OperationId = "TenantBlobDelete")]
        public IActionResult Delete([FromRoute] string channelCode,
            [FromRoute] string appId,
            [FromQuery] string path)
        {
            var _path = string.Empty;

            if (!string.IsNullOrWhiteSpace(path) && path.Length > 1)
            {
                _path = Path.Combine(blobRoot, path.Substring(1));
            }
            else
            {
                _path = blobRoot;
            }

            if (Directory.Exists(_path))
            {
                Directory.Delete(_path, true);
            }

            else if( System.IO.File.Exists(_path))
            {
                System.IO.File.Delete(_path);
            }

            return OK(true);
        }

        [HttpPost("{channelCode}/{appId}")]
        [SwaggerOperation(OperationId = "TenantBlobUpload")]
        public IActionResult Upload([FromRoute] string channelCode,
            [FromRoute] string appId,
            [FromQuery] string path,
            IFormFile file)
        {
            var _path = string.Empty;

            if (!string.IsNullOrWhiteSpace(path) && path.Length > 1)
            {
                _path = Path.Combine(blobRoot, path.Substring(1));
            }
            else
            {
                _path = blobRoot;
            }

            _path = Path.Combine(_path, file.FileName);

            _uploader.Upload(_path, file);

            #region 累计应用文件用量
            _tenantContext.TenantOrders.Add(new TenantOrder()
            {
                Amount = file.Length,
                ChannelAppID = appId,
                ChannelCode = ChannelCodes.AppBlob,
                TenantID = _tenant.Id
            });
            _tenantContext.SaveChanges();
            #endregion

            return OK(AppConst.BlobServer + "/" + _path);
        }

        [HttpPost("{channelCode}/{appId}/CreateFolder")]
        [SwaggerOperation(OperationId = "TenantBlobCreateFolder")]
        public IActionResult CreateFolder([FromRoute] string channelCode,
            [FromRoute] string appId,
            [FromQuery]string path)
        {
            path = HttpUtility.UrlDecode(path);

            if (string.IsNullOrWhiteSpace(path) || path.Length > 32)
            {
                return Error("路径名称为1-32位以内。");
            }

            var _path = Path.Combine(blobRoot, path.Substring(1));

            try
            {
                if (!Directory.Exists(_path))
                {
                    Directory.CreateDirectory(_path);
                }

                return OK(true);
            }
            catch(Exception ex)
            {
                return Error(ex.Message);
            }
        }

        [HttpPost("{channelCode}/{appId}/Rename")]
        [SwaggerOperation(OperationId = "TenantBlobRename")]
        public IActionResult Rename([FromRoute] string channelCode,
            [FromRoute] string appId,
            [FromQuery] string sourceName,
            [FromQuery] string destName)
        {
            sourceName = HttpUtility.UrlDecode(sourceName);
            
            destName = HttpUtility.UrlDecode(destName);

            if (string.IsNullOrWhiteSpace(sourceName) || sourceName.Length > 32)
            {
                return Error("路径名称为1-32位以内。");
            }


            if (string.IsNullOrWhiteSpace(destName) || destName.Length > 32)
            {
                return Error("新的名称为1-32位以内。");
            }


            var _sourceDir = Path.Combine(blobRoot, sourceName.Substring(1));
            var _destDir = Path.Combine(blobRoot, destName.Substring(1));

            try
            {
                if (Directory.Exists(_sourceDir) || System.IO.File.Exists(_sourceDir))
                {
                    Directory.Move(_sourceDir, _destDir);
                }

                return OK(true);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }
    }
}
